﻿using GameBox.Framework;  // for GlobalLogger
using GameBox.Service.ByteStorage;
using WOA.Model;
using UnityEngine;
using UnityEngine.SceneManagement;
using Tanks.Model;


// TanksPush service class.
// 通知客户端进入房间, 游戏开始。
// rpc EnterRoom(EnterRoomMsg)returns(rpc.EmptyMsg);
// 转发对手消息
// rpc PeerMoveTo(PositionMsg)returns(rpc.EmptyMsg);
// rpc PeerRotateTo(RotationMsg)returns(rpc.EmptyMsg);
// rpc PeerFire(FireMsg)returns(rpc.EmptyMsg);
// 伤害
// rpc Damage(DamageMsg)returns(rpc.EmptyMsg);
namespace Tanks
{
    public class TanksPushService
    {
        public void Request(uint id, string method, byte[] content)
        {
            GlobalLogger.L("Request to " + method);
            m_RequestContent = content;
            // 服务方法中会设置不同的应答
            m_ResponseContent = ByteConverter.ProtoBufToBytes<rpc.EmptyMsg>(new rpc.EmptyMsg());

            if ("PeerMoveTo" == method)
                PeerMoveTo();
            else if ("PeerRotateTo" == method)
                PeerRotateTo();
            else if ("PeerFire" == method)
                PeerFire();
            else if ("Damage" == method)
                Damage();
            else if ("EnterRoom" == method)
                EnterRoom();
            else if ("PushFrameMsgList" == method)
                DealFrameMsgList();
            else
            {
                GlobalLogger.L("Ignore method: TanksPush." + method);
                return;
            }

            Rpc.Controller.SendResponse(id, m_ResponseContent);
        }

        private void DealFrameMsgList()
        {
            var frameMsgList = ByteConverter.BytesToProtoBuf<tanks.FrameMsgList>(
                m_RequestContent, 0, m_RequestContent.Length);
            var msgList = frameMsgList.FrameMsgListContent;
            Configure.FrameMsgListStack.Add(msgList);
            /*
            string info = "";
            foreach(var msg in msgList)
            {
                info = "user_id:" + msg.user_id + ", ";
                if (msg.position != null)
                    info += "pos_x : " + msg.position.x + ", ";
                else if (msg.rotation != null)
                    info += "rotation : " + msg.rotation.r + ", ";
                GlobalLogger.L(info);
            }
            */
        }
        private void PeerMoveTo()
        {
            var positionMsg = ByteConverter.BytesToProtoBuf<tanks.PositionMsg>(
                m_RequestContent, 0, m_RequestContent.Length);
            GlobalLogger.L("move to x=" + positionMsg.x + "y=" + positionMsg.y + "z=" +positionMsg.z);
            m_PeerTankMovement.MoveTo(new Vector3(positionMsg.x, positionMsg.y, positionMsg.z));
        }
        private void PeerRotateTo()
        {
            var rotationMsg = ByteConverter.BytesToProtoBuf<tanks.RotationMsg>(
                m_RequestContent, 0, m_RequestContent.Length);
            m_PeerTankMovement.RotateTo(rotationMsg.r);
        }
        private void PeerFire()
        {
            var fireMsg = ByteConverter.BytesToProtoBuf<tanks.FireMsg>(
                m_RequestContent, 0, m_RequestContent.Length);
            m_PeerTankShooting.PeerFire(new Vector3(fireMsg.position.x,fireMsg.position.y,fireMsg.position.z),
                fireMsg.rotation,fireMsg.velocity);

        }
        private void Damage()
        {
            var damageMsg = ByteConverter.BytesToProtoBuf<tanks.DamageMsg>(
                m_RequestContent,0,m_RequestContent.Length);

            uint tank1 = damageMsg.tank1;
            uint tank2 = damageMsg.tank2;

            GlobalLogger.L("tank1=" + tank1 + "======tank2=" + tank2);

            m_SelfTankHealth.TakeDamage(tank1);
            m_PeerTankHealth.TakeDamage(tank2);
        }

        private void EnterRoom()
        {
            if (m_Matched) return;
            m_Matched = true;
            
            var enterRoomMsg = ByteConverter.BytesToProtoBuf<tanks.EnterRoomMsg>(
                m_RequestContent, 0, m_RequestContent.Length);
            m_PeerName = enterRoomMsg.peer_name;
            if (enterRoomMsg.is_peer_tank1)
                m_MyPlayerNumber = 2;
            GlobalLogger.L("对手的名字：" + enterRoomMsg.peer_name);

            SceneManager.LoadScene("CompleteMainScene");
        }

        public static bool IsPeerTank1()
        {
            return m_MyPlayerNumber != 1;
        }

        public static void SetTankMovement(Complete.TankMovement tankMovement)
        {
            if (tankMovement.m_PlayerNumber != m_MyPlayerNumber)
                m_PeerTankMovement = tankMovement;
            else
                m_SelfTankMovement = tankMovement;
        }
        public static void SetTankShooting(Complete.TankShooting tankShooting)
        {
            if (tankShooting.m_PlayerNumber != m_MyPlayerNumber)
                m_PeerTankShooting = tankShooting;
        }
        public static void SetSelfTankHealth(Complete.TankHealth tankHealth)
        {
            if (tankHealth.m_PlayerNumber == m_MyPlayerNumber)
                m_SelfTankHealth = tankHealth;
        }
        public static void SetPeerTankHealth(Complete.TankHealth tankHealth)
        {
            if (tankHealth.m_PlayerNumber != m_MyPlayerNumber)
                m_PeerTankHealth = tankHealth;
        }

        public static int m_MyPlayerNumber = 1;

        private byte[] m_RequestContent;
        private byte[] m_ResponseContent;
        
        private bool m_Matched = false;

        private static string m_PeerName;
        public static Complete.TankMovement m_PeerTankMovement;
        public static Complete.TankMovement m_SelfTankMovement;
        private static Complete.TankShooting m_PeerTankShooting;
        private static Complete.TankHealth m_PeerTankHealth;
        private static Complete.TankHealth m_SelfTankHealth;

    }  // class Client
}  // namespace Rpc
